import {
  ChangeDetectorRef,
  Component,
  EventEmitter,
  Input,
  OnInit,
  Output,
  SimpleChanges,
} from '@angular/core';
import { VulnerabilityProfileEntry } from '@common/types';
import { MatDialog } from '@angular/material/dialog';
import {
  ColDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ValueFormatterParams,
} from 'ag-grid-community';
import { TranslateService } from '@ngx-translate/core';
import { VulnerabilityProfileTableEditCellComponent } from '@routes/vulnerability-profile/vulnerability-profile-table/vulnerability-profile-table-edit-cell/vulnerability-profile-table-edit-cell.component';
import { cloneDeep } from 'lodash';
import { VulnerabilityProfileTableDialogComponent } from '@routes/vulnerability-profile/vulnerability-profile-table/vulnerability-profile-table-dialog/vulnerability-profile-table-dialog.component';
import { ConfirmDialogComponent } from '@components/ui/confirm-dialog/confirm-dialog.component';
import { switchMap } from 'rxjs/operators';
import { VulnerabilityProfileService } from '@routes/vulnerability-profile/vulnerability-profile.service';
import { MultiClusterService } from '@services/multi-cluster.service';
import { Subject } from 'rxjs';
import { AuthUtilsService } from '@common/utils/auth.utils';

@Component({
  selector: 'app-vulnerability-profile-table',
  templateUrl: './vulnerability-profile-table.component.html',
  styleUrls: ['./vulnerability-profile-table.component.scss'],
})
export class VulnerabilityProfileTableComponent implements OnInit {
  private _switchClusterSubscription;
  private _rowData!: VulnerabilityProfileEntry[];
  @Input() set rowData(data: VulnerabilityProfileEntry[]) {
    this._rowData = data;
    this.refreshing$.next(false);
  }
  get rowData() {
    return this._rowData;
  }
  @Input() gridHeight!: number;
  @Input() domains!: string[];
  refreshing$ = new Subject();
  entries!: number;
  @Output() toggleChartView = new EventEmitter();
  gridOptions!: GridOptions;
  gridApi!: GridApi;
  columnDefs: ColDef[] = [
    {
      field: 'id',
      sortable: true,
      resizable: true,
      width: 100,
      headerValueGetter: () => this.translate.instant('general.ID'),
    },
    {
      field: 'name',
      sortable: true,
      resizable: true,
      wrapText: true,
      autoHeight: true,
      cellStyle: { 'line-height': '25px' },
      valueFormatter: this.nameFormatter,
      headerValueGetter: () => 'Vulnerability Fixed',
    },
    {
      field: 'images',
      sortable: true,
      resizable: true,
      headerValueGetter: () =>
        this.translate.instant('cveProfile.gridHeader.IMAGES'),
    },
    {
      field: 'domains',
      sortable: true,
      resizable: true,
      headerValueGetter: () =>
        this.translate.instant('cveProfile.gridHeader.DOMAINS'),
    },
    {
      width: 250,
      field: 'comment',
      sortable: true,
      resizable: true,
      wrapText: true,
      autoHeight: true,
      cellStyle: { 'line-height': '25px' },
      headerValueGetter: () =>
        this.translate.instant('cveProfile.gridHeader.COMMENT'),
    },
    {
      field: 'controls',
      width: 100,
      cellRenderer: 'editCellRenderer',
      cellRendererParams: {
        edit: event => this.editProfile(event),
        delete: event => this.deleteProfile(event),
      },
      cellClass: ['d-flex', 'align-items-center'],
      headerValueGetter: () => '',
    },
  ];

  constructor(
    private translate: TranslateService,
    private vulnerabilityProfileService: VulnerabilityProfileService,
    private multiClusterService: MultiClusterService,
    private cd: ChangeDetectorRef,
    public dialog: MatDialog,
    private authUtilsService: AuthUtilsService
  ) {}

  ngOnInit(): void {
    let isWriteVulsProfileAuthorizaed =
      this.authUtilsService.getDisplayFlag('write_vuls_profile');
    this.entries = this.rowData.length;
    if (!isWriteVulsProfileAuthorizaed) {
      this.columnDefs.pop();
    }
    this.gridOptions = {
      rowData: this.rowData,
      columnDefs: this.columnDefs,
      suppressDragLeaveHidesColumns: true,
      rowSelection: 'single',
      onGridReady: event => this.onGridReady(event),
      components: {
        editCellRenderer: VulnerabilityProfileTableEditCellComponent,
      },
      overlayNoRowsTemplate: this.translate.instant('general.NO_ROWS'),
    };

    //refresh the page when it switched to a remote cluster
    this._switchClusterSubscription =
      this.multiClusterService.onClusterSwitchedEvent$.subscribe(data => {
        this.refresh();
      });
  }

  ngOnDestroy(): void {
    if (this._switchClusterSubscription) {
      this._switchClusterSubscription.unsubscribe();
    }
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (this.gridApi && changes.rowData) {
      this.gridApi.setRowData(changes.rowData.currentValue);
    }
  }

  nameFormatter(params: ValueFormatterParams) {
    console.log(params.node?.data);
    if (params.node?.data.name === '_RecentVulnWithoutFix') {
      return `Vulnerabilities reported within ${params.data.days} day(s) without fix`;
    } else if (params.node?.data.name === '_RecentVuln') {
      return `Vulnerabilities reported within ${params.data.days} day(s)`;
    } else {
      return params.value;
    }
  }

  refresh() {
    this.refreshing$.next(true);
    this.vulnerabilityProfileService.refresh();
  }

  onGridReady(params: GridReadyEvent): void {
    this.gridApi = params.api;
    this.gridApi.sizeColumnsToFit();
    this.gridApi.forEachNode(node =>
      node.rowIndex ? 0 : node.setSelected(true)
    );
    this.cd.markForCheck();
  }

  onResize(): void {
    this.gridApi.sizeColumnsToFit();
  }

  addProfile() {
    this.openDialog();
  }

  editProfile(event): void {
    this.openDialog(cloneDeep(this.gridApi.getRowNode(event.node.id)?.data));
  }

  deleteProfile(event): void {
    let id = this.gridApi.getRowNode(event.node.id)?.data.id;
    const dialogRef = this.dialog.open(ConfirmDialogComponent, {
      maxWidth: '700px',
      data: {
        message: `${this.translate.instant('role.msg.REMOVE_CFM')}${id}`,
      },
      disableClose: true,
    });
    dialogRef.componentInstance.confirm
      .pipe(
        switchMap(() => {
          let name = 'default';
          return this.vulnerabilityProfileService.deleteProfile(name, id);
        })
      )
      .subscribe(
        res => {
          setTimeout(() => this.vulnerabilityProfileService.refresh(), 500);
          dialogRef.componentInstance.onCancel();
          dialogRef.componentInstance.loading = false;
        },
        error => {}
      );
  }

  openDialog(profile?): void {
    const dialog = this.dialog.open(VulnerabilityProfileTableDialogComponent, {
      width: '80%',
      maxWidth: '1100px',
      data: {
        profile,
        domains: this.domains,
      },
    });
    dialog.afterClosed().subscribe(change => {
      if (change) {
        this.vulnerabilityProfileService.refresh();
      }
      this.cd.markForCheck();
    });
  }

  filterCountChanged(event) {
    this.entries = event;
  }
}
